using System;
using System.Collections.Generic;

using IBatisNet.DataMapper;

using log4net;

using GymManager.Exception;
using GymManager.Persistence.VO;

namespace GymManager.Persistence.DAO
{
    /// <summary>
    /// Class responsible by getting information from database about users
    /// </summary>
    public class UserDAO
    {
        // logger instance
        private ILog _logManager = LogManager.GetLogger(typeof(UserDAO));

        /// <summary>
        /// Method responsible by getting an user by its login
        /// </summary>
        /// <param name="String">user's login</param>
        /// <returns>User - user retrieved in according to user's login</returns>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public User findByLogin(String login)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // user value object to be returned
            User userResult = null;

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                userResult = ibatisMapper.QueryForObject<User>("User.findByLogin", login);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving user information", ex);
                throw new PersistenceException("Error while retrieving user information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return userResult;
        }

        /// <summary>
        /// Method responsible by getting user list filtering by som attributes
        /// </summary>
        /// <param name="User">user attributes to be used as filter</param>
        /// <returns>IList - user list filtered</returns>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public IList<User> findByAny(User userVO)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // user list
            IList<User> userList = null;

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                userList = ibatisMapper.QueryForList<User>("User.findByAny", userVO);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving user information", ex);
                throw new PersistenceException("Error while retrieving user information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return userList;
        }

        /// <summary>
        /// Method responsible by getting all active users
        /// </summary>
        /// <returns>IList - list of user value objects</returns>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public IList<User> findAllActive()
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // user list
            IList<User> userList = null;

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                userList = ibatisMapper.QueryForList<User>("User.findAllActive", null);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while retrieving user information", ex);
                throw new PersistenceException("Error while retrieving user information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return userList;
        }


        /// <summary>
        /// Method responsible by adding a new user to database
        /// </summary>
        /// <param name="User">user information to be saved</param>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public void create(User userVO)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                ibatisMapper.Insert("User.insert", userVO);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while saving user information", ex);
                throw new PersistenceException("Error while saving user information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }

        /// <summary>
        /// Method responsible by removing an user from database
        /// </summary>
        /// <param name="Int32">user identifier</param>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public void remove(Int32 userId)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                ibatisMapper.Delete("User.delete", userId);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while removing user information", ex);
                throw new PersistenceException("Error while removing user information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }

        /// <summary>
        /// Method responsible by updating an user to database
        /// </summary>
        /// <param name="User">user information to be saved</param>
        /// <see cref="GymManager.Exception.PersistenceException"/>
        public void update(User userVO)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                ISqlMapper ibatisMapper = DAOManager.getInstance();
                ibatisMapper.Update("User.update", userVO);
            }
            catch (System.Exception ex)
            {
                _logManager.Error("Error while saving user information", ex);
                throw new PersistenceException("Error while saving user information", ex);
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }
    }
}
